import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: xsicrz
 * Date: 5/31/11
 * Time: 9:51 AM
 * To change this template use File | Settings | File Templates.
 */
public class TimelineTableModel extends AbstractTableModel  {



    private static String[] columnNames = {"Jour","Taux %", "Debut", "Fin", "Debut", "Fin", "Total", "Diff"};
    private static Class[] columnClasses = {String.class, String.class, String.class, String.class, String.class, String.class, String.class, String.class, String.class};


    public void setSelectedMonth(int selectedMonth) {
        this.selectedMonth = selectedMonth;
        this.daysOfMonth =  getDaysOfMonth(selectedMonth, selectedYear);

    }

    public void setSelectedYear(int selectedYear) {
        this.selectedYear = selectedYear;
        this.daysOfMonth =  getDaysOfMonth(selectedMonth, selectedYear);
    }

    private Model model = null;

    private int selectedMonth;

    private int selectedYear;

    private List<Date> daysOfMonth;



    public Model getModel() {
        return model;
    }

    public TimelineTableModel(Model model, int selectedMonth, int selectedYear) {
        this.model = model;
        this.selectedMonth = selectedMonth;
        this.selectedYear = selectedYear;
        this.daysOfMonth =  getDaysOfMonth(selectedMonth, selectedYear);
    }

    @Override
    public int getRowCount() {
        return daysOfMonth.size()+1; //+1 Pour le total
    }

    @Override
    public int getColumnCount() {
        return columnNames.length;
    }

    @Override
    public String getColumnName(int column) {
        return this.columnNames[column];    //To change body of overridden methods use File | Settings | File Templates.
    }




    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
         //Affichage du total - Dernière ligne
        if(rowIndex == daysOfMonth.size()) {
            if(columnIndex == 0) {
                return "Total";
            }
            if(columnIndex == 6) {
                return model.humanFormatTotalForMonthAndYear(daysOfMonth);
            }
            if(columnIndex == 7) {
                return model.humanFormatDifferenceForMonthAndYear(daysOfMonth);
            }
            return null;

        }
        //Affichage de la première colonne - Dates du mois
        if(columnIndex == 0)  {
            Date currentDay = daysOfMonth.get(rowIndex);
            return new SimpleDateFormat("dd.MM.yyyy").format(currentDay);
        }

        //On récupère la saisie du jour
        Saisie saisie = this.model.getSaisie(rowIndex+1, selectedMonth, selectedYear);

        if(saisie == null) {
            saisie =new Saisie();
        }
        switch (columnIndex) {
            case 1:
                return String.valueOf(saisie.getTauxActivite());
            case 2:
                if(saisie.getDateMatinDebut() != null)
                    return new SimpleDateFormat("kk:mm").format(saisie.getDateMatinDebut());
                break;
            case 3:
                if(saisie.getDateMatinFin() != null)
                    return new SimpleDateFormat("kk:mm").format(saisie.getDateMatinFin());
                break;
            case 4:
                if(saisie.getDateApresMidiDebut() != null)
                    return new SimpleDateFormat("kk:mm").format(saisie.getDateApresMidiDebut());
                break;
            case 5:
                if(saisie.getDateApresMidiFin() != null) {
                    return new SimpleDateFormat("kk:mm").format(saisie.getDateApresMidiFin());
                }
                break;
            case 6:
                return saisie.getTempsTotalFormatee();
            case 7:
                return saisie.getDifferenceFormatee();
            default:throw new RuntimeException("NON TRAITE");
        }
        return null;
    }

    public boolean isCellEditable(int row, int col) {
        //Note that the data/cell address is constant,
        //no matter where the cell appears onscreen.
        if(row != daysOfMonth.size()) {
            if (col > 0  && col < 6) {
                return true;
            }
        }
        return false;
    }


    public void setValueAt(Object value, int row, int col) {
      //  data[row][col] = value;
        Saisie saisie = this.model.getSaisie(row+1, selectedMonth, selectedYear);
        if(saisie == null) {
            saisie = new Saisie();
            saisie.setDate(daysOfMonth.get(row));
            model.addSaisie(saisie);
        }
        switch (col) {
            case 1:
                {
                    String valueStr = (String)value;
                    try {
                    saisie.setTauxActivite(Integer.valueOf(valueStr));
                    } catch (Exception e) {
                         JOptionPane.showMessageDialog(null, "Veuillez saisir un nombre", "Erreur", JOptionPane.ERROR_MESSAGE);
                    }
                }
                break;
            case 2:
                {
                    String valueStr = (String)value;
                    if(valueStr != null && !"".equals(valueStr.trim())) {
                        try {
                            String[] hourAndMinutes = valueStr.split(":");
                            Calendar calendar = Calendar.getInstance();
                            calendar.setTime(daysOfMonth.get(row));
                            calendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(hourAndMinutes[0]));
                            calendar.set(Calendar.MINUTE, Integer.valueOf(hourAndMinutes[1]));
                            saisie.setDateMatinDebut(calendar.getTime());
                        } catch (Exception e) {
                            JOptionPane.showMessageDialog(null, "Le format doit être 09:01", "Erreur", JOptionPane.ERROR_MESSAGE);
                        }
                    } else {
                        saisie.setDateMatinDebut(null);
                    }
                }
                break;
            case 3:
                 {
                    String valueStr = (String)value;
                    if(valueStr != null && !"".equals(valueStr.trim())) {
                         try {
                            String[] hourAndMinutes = valueStr.split(":");
                            Calendar calendar = Calendar.getInstance();
                            calendar.setTime(daysOfMonth.get(row));
                            calendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(hourAndMinutes[0]));
                            calendar.set(Calendar.MINUTE, Integer.valueOf(hourAndMinutes[1]));
                            saisie.setDateMatinFin(calendar.getTime());
                         }
                        catch (Exception e) {
                            JOptionPane.showMessageDialog(null, "Le format doit être 09:01", "Erreur", JOptionPane.ERROR_MESSAGE);
                        }
                    } else {
                        saisie.setDateMatinFin(null);
                    }
                }
                break;
            case 4:
                  {
                    String valueStr = (String)value;
                    if(valueStr != null && !"".equals(valueStr.trim())) {
                        try {
                            String[] hourAndMinutes = valueStr.split(":");
                            Calendar calendar = Calendar.getInstance();
                            calendar.setTime(daysOfMonth.get(row));
                            calendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(hourAndMinutes[0]));
                            calendar.set(Calendar.MINUTE, Integer.valueOf(hourAndMinutes[1]));
                            saisie.setDateApresMidiDebut(calendar.getTime());
                        }
                        catch (Exception e) {
                            JOptionPane.showMessageDialog(null, "Le format doit être 09:01", "Erreur", JOptionPane.ERROR_MESSAGE);
                        }

                    } else {
                        saisie.setDateApresMidiDebut(null);
                    }
                }
                break;
            case 5:
                 {
                    String valueStr = (String)value;
                    if(valueStr != null && !"".equals(valueStr.trim())) {
                        try {
                        String[] hourAndMinutes = valueStr.split(":");
                        Calendar calendar = Calendar.getInstance();
                        calendar.setTime(daysOfMonth.get(row));
                        calendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(hourAndMinutes[0]));
                        calendar.set(Calendar.MINUTE, Integer.valueOf(hourAndMinutes[1]));
                        saisie.setDateApresMidiFin(calendar.getTime());
                        }
                        catch (Exception e) {
                            JOptionPane.showMessageDialog(null, "Le format doit être 09:01", "Erreur", JOptionPane.ERROR_MESSAGE);
                        }
                    } else {
                        saisie.setDateApresMidiFin(null);
                    }
                }
                break;
        }

        fireTableDataChanged();
    }

    public List<Date> getDaysOfMonth() {
        return daysOfMonth;
    }

    public static List<Date> getDaysOfMonth(int month, int year) {
        Calendar beginOfMonth = Calendar.getInstance();
        beginOfMonth.set(Calendar.DAY_OF_MONTH, 1);
        beginOfMonth.set(Calendar.MONTH, month);
        beginOfMonth.set(Calendar.YEAR, year);
        beginOfMonth.set(Calendar.HOUR_OF_DAY, 0);
        beginOfMonth.set(Calendar.MINUTE, 0);
        beginOfMonth.set(Calendar.SECOND, 0);
        beginOfMonth.set(Calendar.MILLISECOND, 0);
        int minDays = beginOfMonth.getActualMinimum(Calendar.DAY_OF_MONTH);
        int maxDays = beginOfMonth.getActualMaximum(Calendar.DAY_OF_MONTH);

        List<Date> result = new ArrayList<Date>();
        for(int i = minDays; i <= maxDays; i++) {
            beginOfMonth.set(Calendar.DAY_OF_MONTH, i);
            result.add(beginOfMonth.getTime());
        }
        return result;
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        return columnClasses[columnIndex];
    }
}
